package com.zack.paymoudle.alipay;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

import static com.zack.paymoudle.alipay.AliPayConstants.APPID;
import static com.zack.paymoudle.alipay.AliPayConstants.notify_url;

public class OrderInfoTool {



    public static Map<String, String> buildOrderParamMap(String total_amount, String subject, String body) {
        Map<String, String> keyValues = new HashMap<String, String>();

        //对应的APPID请修改为你自己的

        keyValues.put("app_id", APPID);

        //keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"0.01\",\"subject\":\"鑫码快宿\",\"body\":\"入住一晚\",\"out_trade_no\":\"" + getOutTradeNo() +  "\"}");

        String biz_content = getBiz_content(total_amount, subject, body);

        keyValues.put("biz_content",biz_content);

        keyValues.put("charset", "utf-8");

        keyValues.put("method", "alipay.trade.app.pay");

        keyValues.put("sign_type", "RSA2");

        //时间戳，请自己生成。
        keyValues.put("timestamp", "2016-07-29 16:55:53");

        //异步通知回掉地址，请更换为你自己的网址
        keyValues.put("notify_url", notify_url);

        keyValues.put("version", "1.0");

        return keyValues;
    }


    /**
     *
     * @param total_amount 订单总金额，单位为元，精确到小数点后两位
     * @param subject      商品的标题/交易标题/订单标题/订单关键字等。
     * @param body         对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给body。(不为必须)
     * @return string
     * 该函数用于构造商户自己的业务参数，其中有几个参数必须填写。具体请参考https://docs.open.alipay.com/204/105465/
     *
     */
    private static String getBiz_content(String total_amount, String subject, String body){
        JSONObject o = new JSONObject();
        try {
            //product_code，必填参数，固定为QUICK_MSECURITY_PAY
            o.put("product_code","QUICK_MSECURITY_PAY");
            //out_trade_no 商户网站唯一订单号，必填参数,具体怎么生成请按照自己的业务逻辑生成
            o.put("out_trade_no",getOutTradeNo());
            o.put("total_amount",total_amount);
            o.put("subject",subject);
            o.put("body",body);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return o.toString();

    }

	public static String buildOrderParam(Map<String, String> map) {
		List<String> keys = new ArrayList<String>(map.keySet());

		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < keys.size() - 1; i++) {
			String key = keys.get(i);
			String value = map.get(key);
			sb.append(buildKeyValue(key, value, true));
			sb.append("&");
		}

		String tailKey = keys.get(keys.size() - 1);
		String tailValue = map.get(tailKey);
		sb.append(buildKeyValue(tailKey, tailValue, true));

		return sb.toString();
	}
	

	private static String buildKeyValue(String key, String value, boolean isEncode) {
		StringBuilder sb = new StringBuilder();
		sb.append(key);
		sb.append("=");
		if (isEncode) {
			try {
				sb.append(URLEncoder.encode(value, "UTF-8"));
			} catch (UnsupportedEncodingException e) {
				sb.append(value);
			}
		} else {
			sb.append(value);
		}
		return sb.toString();
	}

	public static String getSign(Map<String, String> map, boolean rsa2) {
		List<String> keys = new ArrayList<String>(map.keySet());

        //商户私钥，请替换成你自己的私钥，并对应将支付宝app里的公钥替换成你的
        String rsaKey = AliPayConstants.RSA2_PRIVATE;

		// key排序
		Collections.sort(keys);

		StringBuilder authInfo = new StringBuilder();
		for (int i = 0; i < keys.size() - 1; i++) {
			String key = keys.get(i);
			String value = map.get(key);
			authInfo.append(buildKeyValue(key, value, false));
			authInfo.append("&");
		}

		String tailKey = keys.get(keys.size() - 1);
		String tailValue = map.get(tailKey);
		authInfo.append(buildKeyValue(tailKey, tailValue, false));

		String oriSign = SignUtils.sign(authInfo.toString(), rsaKey, rsa2);
		String encodedSign = "";

		try {
			encodedSign = URLEncoder.encode(oriSign, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "sign=" + encodedSign;
	}



	//唯一的OutTradeNo怎么生成 有什么用？
	private static String getOutTradeNo() {
		SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
		Date date = new Date();
		String key = format.format(date);
		Random r = new Random();
		key = key + r.nextInt();
		key = key.substring(0, 15);
		return key;
	}

	private static String getTimeStamp(){
		long time= System.currentTimeMillis();//long now = android.os.SystemClock.uptimeMillis();
		SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d1=new Date(time);
		String t1=format.format(d1);
		return t1;
	}


    /**
     *
     * @param total_amount 订单总金额，单位为元，精确到小数点后两位
     * @param subject      商品的标题/交易标题/订单标题/订单关键字等。
     * @param body         对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给body。(不为必须)
     * @return
     */
    public static String getOrderInfo(String total_amount, String subject, String body){

        Map<String, String> params = OrderInfoTool.buildOrderParamMap(total_amount, subject, body);
        String orderParam = OrderInfoTool.buildOrderParam(params);
        String sign = OrderInfoTool.getSign(params, true);
        String orderInfo = orderParam + "&" + sign;
        return orderInfo;
    }

}
